#!/usr/bin/env python

from urllib import urlopen
from BeautifulSoup import BeautifulSoup
from random import randint, shuffle
from mechanize import Browser, Request, _http
from cookielib import LWPCookieJar
from time import sleep, time
from re import findall, sub
import formDailiesData as fdd
import traceback
from functools import wraps
from threading import Thread
from os import mkdir
from httplib import IncompleteRead

import logging
logger = logging.getLogger('logfile')
hdlr = logging.FileHandler('logfile.log')
formatter = logging.Formatter('%(asctime)s %(levelname)s %(message)s')
hdlr.setFormatter(formatter)
logger.addHandler(hdlr) 
logger.setLevel(logging.DEBUG)

detailedLogger = logging.getLogger('detLog')
hdlr = logging.FileHandler('detLog.log')
formatter = logging.Formatter('%(asctime)s %(levelname)s %(message)s')
hdlr.setFormatter(formatter)
detailedLogger.addHandler(hdlr) 
detailedLogger.setLevel(logging.DEBUG)

TIMEOUT_TOKEN = "Form submit timed out, abandoned daily"

class TimedOutSubmit(Exception):


  def __init__(self,*args):
    self.args = args or ['Submit timed out']


def retryThrice(fn):
  @wraps(fn)
  def wrapper(*args, **kwargs):
    attempts = 0
    while attempts < 3:
      try:
        if attempts > 0:
          return 'Retried %s times->' % int(attempts) + fn(*args, **kwargs)
        return fn(*args, **kwargs)
      except Exception as e:
        tuserLog('%s attempt %s' % (str(fn), str(attempts)))
        tuserLog(e)
        tuserLog(traceback.format_exc())
        attempts += 1
    return 'Retried 3 times, still failed... neopets is probably just slow'
  return wrapper

def tuserLog(infoToLog, importantLog=False):
  try:
    stuffToLog = '%s' % (infoToLog)
  except:
    stuffToLog = '%s' % (str(infoToLog))
  if importantLog:
    logger.info(stuffToLog)
  detailedLogger.info(stuffToLog)



class RitzBrowser:

  def __init__(self, userAgent, testMode=True):
    self.br = Browser()

    self.cj = LWPCookieJar()
    self.br.set_cookiejar(self.cj)

    self.br.set_handle_equiv(True)
    self.br.set_handle_redirect(True)
    self.br.set_handle_referer(True)
    self.br.set_handle_robots(False)
    self.br.set_handle_refresh(_http.HTTPRefreshProcessor(), max_time=1)
    self.br.addheaders = [('User-agent', userAgent)]
    self.testMode = testMode
    self.currentProxy = {}
    self.resetStatsOnLogin()
    if self.testMode:
      self.shopSpace = 'SHOPSIZE!'
      self.np = 18000
      self.currentPet = '_pet_name_'
      self.hunger = 'Some level of hunger'
      self.mood = 'Some level of mood'
      self.bankTotal = '100000'
    self.currentUrl = 'No url yet'
    self.username = 'TESTMODE'
    self.lastPlayedID = None
    self.hashkey = {}


  def setUpLogs(self):
    try:
      mkdir(self.username+'_logs')
    except OSError:
      pass


  def getLogFile(self,fileName):
    if self.username not in fileName:
      return '%s_%s' % (self.username, fileName)
    return fileName


  def resetStatsOnLogin(self):
    self.np = None
    self.currentPet = ''
    self.hunger = ''
    self.mood = ''
    self.bankTotal = ''
    self.shopSpace = ''


  def doLogin(self, username, password, proxy, sleepSeconds):
    def setProxy(p):
      if p is not None and p != '':
        self.br.set_proxies(proxies={"http": p})
      else:
        self.br.set_proxies(proxies={})

    if not self.testMode:
      setProxy(proxy)

      if self.username != username:
        self.resetStatsOnLogin()
      self.username = username
      self.password = password
      try:
        self.cj.load('%s.cj' % username)
      except IOError as e:
        pass
      firstPage = self.doOpen('http://www.neopets.com/', loginCheck=False)
      if 'userlookup.phtml?user=%s' % (username) in repr(str(firstPage)):
        self.currentProxy = proxy
        self.setUpLogs()
        setProxy(self.currentProxy)
        return 'Successful login'
      self.doSleep(sleepSeconds)
      req = Request('http://www.neopets.com/login.phtml', 'destination=%252F'+'index.phtml&username=%(username)s&password=%(password)s' % {'username':username, 'password':password} )
      self.doOpen(req, 'logs/afterLoginResponse.html', loginCheck=False)
      setProxy(self.currentProxy)
      resp = self.doOpen('http://www.neopets.com/index.phtml', 'logs/pageAfterLogin.html')
      self.saveCookie()
      if 'userlookup.phtml?user=%s' % (username) in repr(str(resp)):
        self.currentProxy = proxy
        self.setUpLogs()
        return 'Successful login'
      setProxy(self.currentProxy)
      return 'Login Failed!'
    return 'Successful login'


  def saveCookie(self):
    self.cj.save('%s.cj' % self.username)


  def determineOutcome(self, dailyReg, htmlResponse):
#                    <table align=center width=400><tr><td bgcolor='#ffffcc' width=400 align=center colspan=2 cellpadding=3><b>Something has happened!</b></td></tr><tr><td width=80><img src='http://images.neopets.com/events/evil_ghost.gif' border=1 height=80 width=80></td><td width=320>A Ghost cackles insanely and steals 40 Neopoints from you...<br></td></tr></table><p><center>Next match: <b>Tuesday</b> the <b>3 rd</b> at <b>02:00 PM NST</b></center><p>
    resultList = []
    allReg = dailyReg + [('loss',"Tried clicking the form .+ slow right now"), ('loss',TIMEOUT_TOKEN)]
    for outcome, reg in allReg:
      if findall( reg, htmlResponse):
        res = str(findall( reg, htmlResponse)[0])
        resultList.append( sub("</?[^\W].{0,1000}?>",'', res) )
    if len(resultList)>0:
      return ', '.join(resultList)
    if htmlResponse == "Couldn't find form to submit":
      return htmlResponse
    if """Enter your username in the box below and we will send your password to your account's email address.""" in htmlResponse:
      return "Got logged out"


  def timeoutSubmit(self, timeout, raiseExc = False):
    total_attempts = 3
    self.userLog('Attempting submit')
    t = TimeoutSubmit(self.br)
    t.start()
    for i in range(timeout):
      sleep(1)
      self.userLog('Waited: %ss' % str(i))
      if t.isComplete():
        return t.retVal
    if raiseExc:
      raise TimedOutSubmit()
    return TimedOutReq()


  def selectAndSubmit(self, index, fileToWrite, submitDict = None, raiseExc = False):
    if self.testMode:
      return 'TestMode, probly did something?'

    self.br.select_form(nr=index)
    if submitDict:
      for key in submitDict:
        self.br[key] = submitDict[key]
    resp = self.timeoutSubmit(15, raiseExc)

    htmlResponse = resp.read()
    with open(self.getLogFile(fileToWrite), 'w') as f:
      f.write(htmlResponse)
    return htmlResponse

  def getDaily2Urls( self, sleepSeconds, data ):
    resp = self.doOpen(data['url'])
    self.doSleep(sleepSeconds)
    if not self.testMode and ( 'phraseInForm' not in data or data['phraseInForm'] in resp):
      resp2 = self.doOpen(data['url2'])
      htmlResponse = resp2
      with open(self.getLogFile(data['fileToWrite']), 'w') as f:
        f.write(htmlResponse)
      return self.determineOutcome( data['reg'], htmlResponse )
    return 'TestMode, probly did something?'


  @retryThrice
  def getLunarTemple(self, sleepSeconds):
    data = fdd.dailyData['Lunar Temple']
    self.doOpen( data['url'] )
    self.doSleep( sleepSeconds.pop() )
    moonHtml = self.doOpen( data['url2'], 'logs/lunarb4.html' )
    if "You may only attempt my challenge once per day. Please try again tomorrow!" in moonHtml:
      return "You may only attempt my challenge once per day. Please try again tomorrow!"
    if self.testMode:
      return "Testmode"
    angle = int(findall('angleKreludor=(\d+)', moonHtml)[0])
    angleMapping = [
[0,   11,  8],
[12,  33,  9],
[34,  56,  10],
[57,  78,  11],
[79,  101, 12],
[102, 123, 13],
[124, 146, 14],
[147, 168, 15],
[169, 191, 0],
[192, 213, 2],
[214, 236, 2],
[237, 258, 3],
[259, 281, 4],
[282, 303, 5],
[304, 326, 6],
[327, 348, 7],
[349, 360, 8]
]
    for a in angleMapping:
      if a[0]<=angle<=a[1]:
        index = str(a[2])
        break
    prizeHtml = self.selectPhraseAndSubmit( sleepSeconds.pop(), data, {'phase_choice': [index]} )
    return self.determineOutcome( data['reg'], prizeHtml )


  @retryThrice
  def getTriviaQuestion(self, sleepSeconds):
    data = fdd.dailyData["Trivia Question"]
    def getCorrectAnswer():
      resp = urlopen(data['externalurl'])
      answerHtml = resp.read()
      soup = BeautifulSoup(answerHtml)
      answerbox = soup.findAll('td', attrs={'valign':'top', 'align':'left','width':'50%'})[0]
      return findall("""<strong class="bbc">Answer:</strong> (.+)<br />""", str(answerbox))[0]

    resp = self.doOpen(data['url'],'logs/trivialb4.html')
    if not self.testMode:
      soup = BeautifulSoup(resp)
      try:
        trivia_repsonses = str(soup.findAll('select', attrs={'name':'trivia_response'})[0])
      except:
        return "Must have already done this today"
      answerMap = {}
      responseSoup = BeautifulSoup(trivia_repsonses)
      for o in responseSoup.findAll('option'):
        answerMap[str(o.contents[0])] = str(o.attrs[0][1])
      answer = getCorrectAnswer()
      if answer in answerMap:
        guessHtml = self.selectPhraseAndSubmit( sleepSeconds, data, {'trivia_response': [answerMap[answer]] })
        return self.determineOutcome( data['reg'], guessHtml)
      return "Couldn't find correct answer!"
    return "Test mode"


  def getDailyGenericFlash(self, sleepSeconds, data):
    url, referer, fileToWrite, reg, requestToSend = data['url'], data['referer'], data['fileToWrite'], data['reg'], data['requestToSend']
    resp = self.doOpen(url)
    with open(self.getLogFile('logs/b4wheel.html'),'w') as f:
      f.write(resp)
    refVal = findall( referer, resp )
    if len(refVal)>0 and not self.testMode:
      self.doSleep(sleepSeconds)
      req = Request(requestToSend[0], requestToSend[1])
      req.add_header("Referer", refVal[0])
      self.cj.add_cookie_header(req)
      resp = self.doOpen(req, fileToWrite, loginCheck=False)
      strResp = sub(r'[^\w]','',safe_str(resp) )
      return self.determineOutcome( reg, str(strResp) )
    return self.determineOutcome(reg, str(resp))



  def selectPhraseAndSubmit(self, sleepSeconds, data, submitDict=None, raiseExc = False):
    formIndex = self.findFormIndexByStr(data['phraseInForm'])
    if formIndex is not False or formIndex == 0:
      self.doSleep(sleepSeconds)
      return self.selectAndSubmit(formIndex, data['fileToWrite'], submitDict, raiseExc)
    return "Couldn't find form to submit"


  def findFormIndexByStr(self, phraseInForm):
    for index, form in enumerate(self.br.forms()):
      if phraseInForm in str(form).replace('\n',''):
        return index
    return False


  def getDailyGenericForm(self, sleepSeconds, data):
    url, phraseInForm, fileToWrite, reg = data['url'], data['phraseInForm'], data['fileToWrite'], data['reg']
    if self.testMode:
      return 'TestMode, probly did something?'

    r = self.doOpen(url)
    resp = self.selectPhraseAndSubmit(sleepSeconds, data, raiseExc = True)
    return self.determineOutcome( reg, resp )


  @retryThrice
  def getPotatoCounter(self, betweenCountSleepList, sleepSecondsList):
    def doGuess(sleepSec, html, fileToWrite, data):
      return self.selectPhraseAndSubmit(sleepSec, data, {'guess' : self.countPotatoes(html)}, raiseExc = True )

    data = fdd.dailyData['Potato Counter']
    resp = self.doOpen( data['url'] )
    if not self.testMode:
      retVal = []
      for i in range(3):
        try:
          resp = doGuess(sleepSecondsList.pop(), resp, 'logs/potato%s.html' % i, data)
        except TimedOutSubmit:
          return '[%s] - Hit a timeout, stopping the daily' % str(retVal)
        except:
          return 'Possibly already done this?  Couldnt find form'
        retVal.append( self.determineOutcome( data['reg'], resp ) )
        if i != 2:
          formIndex = self.findFormIndexByStr('Play Again')
          if formIndex:
            self.doSleep( betweenCountSleepList.pop())
            resp = self.selectAndSubmit(formIndex, 'logs/potatoRESP%s.html' % i)
          else: break
      return str(retVal) or "You may have already done this today"
    return "TESTMODE"


  @retryThrice
  def countPotatoes(self, html):
    potato1 = """<img src='http://images.neopets.com/medieval/potato1"""
    potato2 = """<img src='http://images.neopets.com/medieval/potato2"""
    potato3 = """<img src='http://images.neopets.com/medieval/potato3"""
    potato4 = """<img src='http://images.neopets.com/medieval/potato4"""

    total = 0
    for line in html.split('\n'):
      if '<table align=center cellpadding=3 cellspacing=0 border=0><tr' in line:
        total+= line.count(potato1)
        total+= line.count(potato2)
        total+= line.count(potato3)
        total+= line.count(potato4)
    return str(total)


  @retryThrice
  def getBagatelle(self, sleepSeconds, sleepSecondsArray):
    def doRequest(input, requestToSend, referer, fileToWrite):
      if not self.testMode:
        req = Request(requestToSend[0] % (input), requestToSend[1])
        req.add_header("Referer", referer)
        self.cj.add_cookie_header(req)
        resp = self.doOpen(req, fileToWrite % (input), loginCheck=False)
        return resp
      else:
        return 'points=250&totalnp=1555&prize_id=&success=RRLL&error=So+close...' #similar to a regular response

    data = fdd.dailyData['20x Bagatelle']
    url = data['url']
    reg = data['reg']
    requestToSend = data['requestToSend']
    referer = data['referer']
    fileToWrite = data['fileToWrite']
    resp = self.doOpen(url)
    randomNums = [randint(1,99999) for i in range(20)]
    results = []
    self.doSleep(sleepSeconds)
    for i in randomNums:
      self.doSleep(sleepSecondsArray.pop())
      resp = doRequest(i, requestToSend, referer, fileToWrite)
      outcome = self.determineOutcome(reg, resp)
      results.append( outcome )
    return results


  @retryThrice
  def getGrumpyKing(self, sleepSeconds, longSleepSeconds):
    def doGrumpy(i):
      data = fdd.dailyData['Grumpy King']
      resp = self.doOpen(data['url'], 'logs/grumpyb4-%s.html' % i)
      if not self.testMode:
        soup = BeautifulSoup(resp)
        selectionDict = {}
        for item in ['qp1', 'qp2', 'qp3', 'qp4', 'qp5', 'qp6', 'qp7', 'qp8', 'qp9', 'qp10', 'ap1', 'ap2', 'ap3', 'ap4', 'ap5', 'ap6', 'ap7', 'ap8']:
          qp1 = soup.findAll('select', attrs={'name' : item} )
          if len(qp1)==0:
            return 'No form, probably out to lunch'
          l = [option.attrs[0][1] for option in qp1[0].findAll('option')]
  #          while ' ' in selection or ',' in selection or '-' in selection:
          selection = l[randint(1,len(l)-1)]
          selectionDict[item] = [selection]

        resp2 = self.selectPhraseAndSubmit(longSleepSeconds.pop(), data, selectionDict)
        return self.determineOutcome( data['reg'], resp2)
    results = []
    results.append(doGrumpy('1'))
    self.doSleep( sleepSeconds )
    results.append(doGrumpy('2'))
    return str(results)


  @retryThrice
  def getForgottenShore(self, sleepSeconds):
    data = fdd.dailyData['Forgotten Shore']
    resp = self.doOpen(data['url'], data['fileToWrite'])
    if "nothing of interest to be found today" in str(resp):
      return "Nothing of interest today"
    if "Neopets - Krawk Island" in str(resp):
      return "Have not done forgotten shore puzzle yet"
    if "confirm=1" not in str(resp):
      "Not sure what we've encountered... maybe the daily has changed"
    self.doSleep( sleepSeconds )
    try:
      ref_ck = findall( data['ref_ck'], str(resp) )[0]
      resp = self.doOpen( data['url2'] % ref_ck, data['fileToWrite2'] )
      return self.determineOutcome( data['reg'], resp)
    except Exception as e:
      return "Unknown problem"

  def getWishingWell(self, sleepSeconds, amount, wish ):
    data = fdd.dailyData['Wishing Well']

    submitDict = {'donation': str(amount), 'wish' : str(wish)}
    if self.testMode:
      return "testmode, probably did something"
 
    for e in range(5):
      self.doSleep(sleepSeconds.pop())
      self.doOpen(data['url'], data['fileToWrite'])
      formIndex = self.findFormIndexByStr(data['phraseInForm'])
      if formIndex is not False or formIndex == 0:
        self.doSleep(sleepSeconds.pop())
        self.selectAndSubmit(formIndex, data['filesToWrite'] % str(e), submitDict)
    return "Wished 5 times with [%s]np for [%s]" % (amount, wish)


  @retryThrice
  def getWiseKing(self, sleepSeconds):
    data = fdd.dailyData['Wise King']
    resp = self.doOpen(data['url'], 'logs/wiseb4.html')
    if not self.testMode:
      soup = BeautifulSoup(resp)
      selectionDict = {}
      for item in ['qp1', 'qp2', 'qp3', 'qp4', 'qp5', 'qp6', 'qp7']:
        qp = soup.findAll('select', attrs={'name' : item} )
        if len(qp)==0:
          return 'No form, probably out to lunch'
        l = [option.attrs[0][1] for option in qp[0].findAll('option')]
#          while ' ' in selection or ',' in selection or '-' in selection:
        selection = l[randint(1,len(l)-1)]
        selectionDict[item] = [selection]
      resp2 = self.selectPhraseAndSubmit(sleepSeconds, data, selectionDict)
      return self.determineOutcome( data['reg'], resp2)
    return "Test mode, probably did something"


  @retryThrice
  def sellStocks(self, sleepSeconds, min):
    data = fdd.dailyData['Sell Stocks']

    resp = self.doOpen(data['url'], data['firstFileToWrite'])
    soup = BeautifulSoup(resp)
    prices = {}
    for e in soup.findAll('tr'):
      tds = e.findAll('td', {'align':'center'})
      if len(tds)>2 and 'type=buy' in str(tds[1]):
        prices[tds[1].findAll('a')[0].contents[0]] = tds[3].contents[0].strip()
    stocksToSell = [stock for stock in prices if int(prices[stock])>=min]
    sellingDict = {}
    for e in stocksToSell:
      sellTok = 'sell[%s]' % e
      for table in soup.findAll('table', {'cellpadding':'3', 'width' : '100%'}):
        if sellTok in str(table):
          for tr in table.findAll('tr'):
            if sellTok in str(tr):
              tds = tr.findAll('td')
              link1 = tds[5]
              if len(tds)>6:
                link1 = tds[6]
              if sellTok in str(link1):
                for e in link1.findAll('input')[0].attrs:
                  if e[0] == 'name':
                    ele = e[1]
                    amount = str(tr.findAll('td')[0].contents[0]).replace(',','')
                    sellingDict[ele] = amount
    if sellingDict:
      resp = self.selectPhraseAndSubmit(sleepSeconds, data, sellingDict)
      return self.determineOutcome( data['reg'], resp)
    return "No stocks over %s to sell" % min


  @retryThrice
  def getStocks(self, sleepSeconds, max):
    data = fdd.dailyData['Buy 1000x Stocks']
    stocksHtml = self.doOpen( data['url'], 'logs/stockslisting.html' )
    self.doSleep( sleepSeconds.pop() )
    if self.testMode:
      return 'Did stocks'
    stockLink, ticker, cost = self.getFifteenStockLink(stocksHtml, max)
    if not stockLink:
      return "Couldn't find any stocks cheap enough"
    url = 'http://www.neopets.com/%s' % stockLink
    if self.testMode:
      with open('testStuff/stocksURL2.html','r') as f:
        stockInfoHtml = f.read()
    else:
      stockInfoHtml = self.doOpen(url, 'logs/stocks.html')
    self.doSleep( sleepSeconds.pop())
    soup = BeautifulSoup(stockInfoHtml)
    stockTable = str(soup.findAll('table', attrs={'align':'center', 'cellpadding':'3', 'cellspacing':'0', 'width':'500'})[0].contents)
    buyExt = findall("""href="(.+)"><b><font""", stockTable)[0].replace('amp;','')
    buyUrl = 'http://www.neopets.com/%s' % buyExt
    self.doOpen(buyUrl)
    if self.testMode:
      with open('testStuff/stocksYouCannotAfford.html','r') as f:
        boughtShares = f.read()
    else:
      boughtShares = self.selectPhraseAndSubmit( sleepSeconds.pop(), data, data['postData'] )
    outcome = self.determineOutcome( data['reg'], boughtShares )
    if outcome is None:
      return 'Bought 1000 %s stocks at %s' % (ticker, str(cost))
    return outcome


  @retryThrice
  def getFifteenStockLink(self, html, max):
    if self.testMode:
      with open('testStuff/stocksLink.html','r') as f:
        soup = BeautifulSoup(f.read())
    else:
      soup = BeautifulSoup(html)
    table = soup.findAll('table',attrs={'cellpadding':'3','cellspacing':'0','border':'1'})[0]
    stockDict = {}
    for tr in table.findAll('tr'):
      ticker = sub("</?[^\W].{0,100}?>",'', str(tr.findAll('td')[1].contents[0]))
      cost = sub("</?[^\W].{0,100}?>",'', str(tr.findAll('td')[5].contents[0]))
      link = findall('href="(.+)"><b>',str(tr.findAll('td')[1].contents))
      if len(link)>0:
        stockDict[ticker] = {'cost':cost, 'link':link}
    matchingDict = {}
    for stock in stockDict:
      cost = int(stockDict[stock]['cost'])
      try:
        if 15 <= cost <= int(max):
          if cost not in matchingDict:
            matchingDict[cost] = []
          matchingDict[cost].append( (stock, stockDict[stock]['link'][0]) )
      except Exception as e:
        print max
        print e
        if 15 <= cost <= int(max):
          if cost not in matchingDict:
            matchingDict[cost] = []
          matchingDict[cost].append( (stock, stockDict[stock]['link'][0]) )

    if len(matchingDict)>0:
      for i in range(15,int(max)+1):
        if i in matchingDict:
          return matchingDict[i][0][1].replace('amp;',''), matchingDict[i][0][0], i
    return (None, None, None)


  @retryThrice
  def getToyChest(self, sleepSeconds):
    data = fdd.dailyData['Toy Chest']
    self.doOpen( data['url'] )
    self.doSleep( sleepSeconds )
    resp = self.doOpen( data['url'], data['fileToWrite'], data['postData'] )
    return self.determineOutcome( data['reg'], resp )


  @retryThrice
  def getMeteor(self, sleepSeconds):
    data = fdd.dailyData['Meteor']
    resp = self.doOpen(data['url'], 'logs/firstMeteor.html')
    self.doSleep( sleepSeconds.pop() )
    if not self.testMode and "It's gone!" not in resp:
      secondPage = self.selectPhraseAndSubmit( sleepSeconds.pop(), data )
      if "It's gone!" in secondPage:
        return "It's gone!"
      formIndex = self.findFormIndexByStr(data['phraseInForm2'])
      if formIndex is not False or formIndex == 0:
        self.doSleep( sleepSeconds.pop() )
        prizeHtml = self.selectAndSubmit(formIndex, 'logs/meteorPrize.html', {'pickstep': ['1']})
        return self.determineOutcome( data['reg'], prizeHtml)
      return "Couldn't find form to submit"
    return "It's gone"


  @retryThrice
  def getSnowager(self, sleepSeconds):
    data = fdd.dailyData['Snowager']
    resp = self.doOpen(data['url'], 'logs/firstSnowager.html')
    if 'The Snowager is awake' in resp:
      return "Snowager is awake"
    req = Request(data['url2'])
    req.add_header("Referer", data['url'])
    self.cj.add_cookie_header(req)
    self.doSleep(sleepSeconds)
    prizeHtml = self.doOpen(req, data['fileToWrite'])
    return self.determineOutcome( data['reg'], prizeHtml )


  def setBankTotal(self, html):
    soup = BeautifulSoup(html)
    for tr in soup.findAll('table', attrs={'width':'100%', 'cellpadding' : '4'}):
      self.bankTotal = findall('bold;">(\S+ NP)', str(tr))[0]


  @retryThrice
  def getBankDeposit(self, sleepSeconds, multipleToDeposit, depositUntilUnder):
    data = fdd.dailyData['Bank Deposit']
    url, phraseInForm, fileToWrite, reg = data['url'], data['phraseInForm'], data['fileToWrite'], data['reg']
    resp = self.doOpen(url, 'logs/beforeDeposit.html')
    if not self.testMode:
      self.setBankTotal(resp)

      formIndex = self.findFormIndexByStr(data['phraseInForm'])
      if formIndex is not False or formIndex == 0:
        self.doSleep(sleepSeconds)
        amountToDeposit = 0
        while int(self.getNP())-int(amountToDeposit) > int(depositUntilUnder):
          amountToDeposit += int(multipleToDeposit)
        if amountToDeposit==0:
          return "No need to deposit funds"
        data['postData']['amount'] = str(amountToDeposit)
        resp = self.selectAndSubmit(formIndex, data['fileToWrite'], data['postData'])
        self.setBankTotal(resp)
        return "Currently have %s on hand" % (self.getNP())
      return "Couldn't find form index"
    return 'TestMode, probly did something?'


  @retryThrice
  def getBankInterest(self, sleepSeconds):
    data = fdd.dailyData['Bank Interest']
    url, phraseInForm, fileToWrite, reg = data['url'], data['phraseInForm'], data['fileToWrite'], data['reg']

    if self.testMode:
      return 'TestMode, probly did something?'

    resp = self.doOpen(url, 'logs/beforeInterest.html')
    if not self.testMode:
      self.setBankTotal(resp)
      if "You have already collected your interest today." not in resp:
        if "You have deposited and/or withdrawn Neopoints today." not in resp:
          resp = self.selectPhraseAndSubmit(sleepSeconds, data)
          self.setBankTotal(resp)
          return self.determineOutcome( reg, resp )
        return "You have deposited and/or withdrawn Neopoints today."
      return "Already collected interest"
    return 'Tried clicking the form button 3 seperate times, giving up, neopets must be slow right now'


#  @retryThrice
  def getFoodClub(self, sleepSeconds, userMinProb, userMinPay):
    ARENAS = ['Shipwreck', 'Lagoon', 'Treasure Island', 'Hidden Cove', "Harpoon Harry's"]
    if self.testMode:
      return 'Food club'

    def getChancesDict():
      resp = urlopen('http://foodclub.daqtools.info/')
      html = resp.read()
      soup = BeautifulSoup(html)
      try:
        trs = soup.findAll('table')[0].findAll('tr')
      except:
        return False
      chancesDict = {}
      for index, tr in enumerate(trs):
        for arena in ARENAS:
          if arena in str(tr):
            chancesDict[arena] = {}
            for i in range(4):
              tdList = trs[index+i].findAll('td')
              if len(tdList)>9: tdList.pop(0)
              name = tdList[0].contents[0]
              prob = float( tdList[1].contents[0].replace('%','') )
              pay  = float( tdList[2].contents[0].replace('%','') )
              chancesDict[arena][name] = {'prob':prob, 'pay':pay}
      return chancesDict


    def getValueMappings(html):
      s = BeautifulSoup(html)
      valueDict = {}
      arenaName = ''
      for e in s.findAll('tr', attrs={'bgcolor':'white'}):
        for f in e.findAll('td'):
          optionsDict = {}
          for b in f.findAll('b'):
            if b.contents[0]:
              arenaName = b.contents[0]
          valueDict[arenaName] = {o.contents[0].split('&nbsp;')[0].strip() : o.attrs[0][1] for o in f.findAll('option')}
          for s in f.findAll('select'):
            valueDict[arenaName]['selectName'] = s.attrs[0][1]
      return valueDict


    def getParticipantsToBetOn(cd):
      participantsToBetOn = {e:[] for e in cd}
      for e in cd:
        for participant in cd[e]:
          if cd[e][participant]['prob']>50 and cd[e][participant]['pay'] >= 0:
            participantsToBetOn[e].append(participant)
      return participantsToBetOn


    def placeBet(amount, matches, phraseInForm, submitDict, logFileB4, logFileAfter, url, sleepSeconds, openURLFirst=True):
      if openURLFirst:
        resp = self.doOpen(url, logFileB4)
        self.doSleep(sleepSeconds)

      formIndex = self.findFormIndexByStr(phraseInForm)
      self.br.select_form(nr=formIndex)
      self.br['matches[]'] = matches
      for e in submitDict:
        self.br[e] = [submitDict[e]]
      self.br['bet_amount'] = betAmount

      resp = self.br.submit()
      htmlResponse = resp.read()
      with open(self.getLogFile(logFileAfter), 'w') as f:
        f.write(htmlResponse)

      return htmlResponse


    def generateSubmitDict(participantsToBetOn, valDict):
      submitDict = {}
      for p in participantsToBetOn:
        for e in participantsToBetOn[p]:
          submitDict[valDict[p]['selectName']] = valDict[p][e]
      return submitDict


    def collectFoodClub(sleepSeconds1, sleepSeconds2):
      self.doSleep(sleepSeconds1)
      resp = self.doOpen("http://www.neopets.com/pirates/foodclub.phtml?type=collect", "logs/beforeCollectWinnings.html")
      if 'Collect Your Winnings' in str(resp):
        try:
          self.doSleep(sleepSeconds2)
          req = Request('http://www.neopets.com/pirates/process_foodclub.phtml', 'type=collect')
          self.doOpen(req, 'logs/AfterCollectFoodClub.html')
          return "Collected Food Club winnings\n"
        except Exception as e:
          return "Did not collect any food club winnings\n"
      return "No winnings today"

    collected = collectFoodClub(sleepSeconds.pop(), sleepSeconds.pop())

    cd = getChancesDict()
    if cd:
      participantsToBetOn = getParticipantsToBetOn(cd)
      data = fdd.dailyData['Food club']
      resp = self.doOpen(data['url'], data['fileToWrite'])
      betAmount = findall("""You can only place up to <b>(\d+)</b> NeoPoints per bet""", resp)[0]
      valDict = getValueMappings(resp)
      submitDict = generateSubmitDict(participantsToBetOn, valDict)
      matches = [e[-1] for e in submitDict]
      self.doSleep(sleepSeconds.pop())
      htmlResponse = ''
#      htmlResponse = placeBet(betAmount, matches, data['phraseInForm'], submitDict, data['fileToWrite'], data['fileToWrite2'], data['url'], False, openURLFirst=False) # bet on all of them

      for match in matches:
        self.doSleep(sleepSeconds.pop())
        matchSubDict = {'winner%s' % match : submitDict['winner%s' % match]}
        htmlResponse = placeBet(betAmount, [match], data['phraseInForm'], matchSubDict, 'logs/foodClubBid_%s.html' % match, 'logs/foodClubBid_after_%s.html' % match, data['url'], sleepSeconds.pop(), openURLFirst=True)

      total_winnings = self.determineOutcome(data['reg'], htmlResponse)
      return collected + "Total possible winnings: %s [%s bets]" % (total_winnings, str(len(matches)+1))
    else:
      return collected + "Can't do food club right now, statistics site is still updating"


  @retryThrice
  def getAltador(self, sleepSecondsList):
    data = fdd.dailyData['Altador']
    resp = self.doOpen(data['url'], data['fileToWrite'] )
    self.doSleep(sleepSecondsList.pop())
    if data['phraseInForm'] in resp:
      link = findall(data['regForURL'], resp)
      if len(link)==0:
        return "Could not find link, have you done Altador Plot?"
      req = Request('http://www.neopets.com/%s' % (link[0]) )
      req.add_header("Referer", data['url'])
      self.cj.add_cookie_header(req)
      resp = self.doOpen(req, data['fileToWrite2'])
      if "You've already received your free prize today" in resp:
        return "You've already received your free prize today!"

      formIndex = self.findFormIndexByStr(data['phraseInForm2'])
      if formIndex is not False or formIndex == 0:
        self.doSleep(sleepSecondsList.pop())
        resp = self.selectAndSubmit(formIndex, data['fileToWrite3'])
        return self.determineOutcome(data['reg'], resp)
      return "Couldn't find form to submit"
    return "You may not have done the Altador Plot..."


  def getMerryGoRound(self, sleepSeconds):
    data = fdd.dailyData['Merry Go Round']
    goodMoods = ['cheerful', 'extremely happy', 'joyful', 'delighted!']
    if self.testMode:
      return 'TestMode, probly did something?'

    if self.mood in goodMoods:
      return 'Too happy to do merry go round'

    if self.mood in ['']:
      return 'Unknown mood, not doing merry go round'

    if not self.currentPet:
      return "Not sure which pet is yours at this point"

    maxRides = 3
    numRides = 0

    while numRides < maxRides and self.mood.lower() not in goodMoods:
      r = self.doOpen(data['url'], data['fileToWrite'] % str(numRides))

      formIndex = self.findFormIndexByStr(data['phraseInForm'])
      if formIndex is not False or formIndex == 0:
        self.doSleep(sleepSeconds.pop())

        self.br.select_form(nr=formIndex)
        self.br['chosenone'] = [self.currentPet]
        resp = self.br.submit()

        htmlResponse = resp.read()
        with open(self.getLogFile(data['fileToWrite2'] % str(numRides)), 'w') as f:
          f.write(htmlResponse)
        outcome = self.determineOutcome( data['reg'], htmlResponse )
        if outcome != """I hope you enjoyed your ride, come again soon""":
          return 'Unknown outcome after riding on merry go round'
        numRides += 1
        self.doSleep(sleepSeconds.pop())
      else:
        return "Couldn't find form to submit"
    return "Rode on merry go round %s times." % str(numRides)


  @retryThrice
  def getWheelOfExcitement(self, sleepSeconds):
    return self.getDailyGenericFlash(sleepSeconds, fdd.dailyData["Wheel of Excitement"])

  @retryThrice
  def getSlug(self, sleepSeconds):
    return self.getDaily2Urls( sleepSeconds, fdd.dailyData['Slug'])

  @retryThrice
  def getBobApples(self, sleepSeconds):
    return self.getDaily2Urls( sleepSeconds, fdd.dailyData['Bob4Apples'])

  @retryThrice
  def getJelly(self, sleepSeconds):
    return self.getDailyGenericForm( sleepSeconds, fdd.dailyData['Jelly'])

  @retryThrice
  def getOmelette(self, sleepSeconds):
    return self.getDailyGenericForm( sleepSeconds, fdd.dailyData['Omelette'])

  @retryThrice
  def getAnchor(self, sleepSeconds):
    return self.getDailyGenericForm( sleepSeconds, fdd.dailyData['Anchor'] )

  @retryThrice
  def getShrine(self, sleepSeconds):
    return self.getDailyGenericForm( sleepSeconds, fdd.dailyData['Shrine'] )

  @retryThrice
  def getIceScratchCard(self, sleepSeconds):
    return self.getDailyGenericForm( sleepSeconds, fdd.dailyData['Ice Scratch Card'] )

  @retryThrice
  def getDesertScratchCard(self, sleepseconds):
    return self.getDailyGenericForm( sleepseconds, fdd.dailyData['Desert Scratch Card'] )

  @retryThrice
  def getHalloweenScratchCard(self, sleepSeconds):
    return self.getDailyGenericForm( sleepSeconds, fdd.dailyData['Halloween Scratch Card'] )

  @retryThrice
  def getFruitMachine(self, sleepSeconds):
    return self.getDailyGenericForm( sleepSeconds, fdd.dailyData['Fruit Machine'] )

  @retryThrice
  def getPlushieOfProsperity(self, sleepSeconds):
    return self.getDailyGenericForm( sleepSeconds, fdd.dailyData['Plushie Of Prosperity'] )

  @retryThrice
  def getFishing(self, sleepSeconds):
    return self.getDailyGenericForm( sleepSeconds, fdd.dailyData['Fishing'] )

  @retryThrice
  def getTombola(self, sleepSeconds):
    return self.getDailyGenericForm( sleepSeconds, fdd.dailyData['Tombola'] )

  @retryThrice
  def getHealingSprings(self, sleepSeconds):
    return self.getDailyGenericForm( sleepSeconds, fdd.dailyData['Healing Springs'] )


  @retryThrice
  def getAuctionFromFile(self, sleepSecondsList):
    data = fdd.dailyData['Auction From Shop']

    if self.testMode:
      return 'Items auctioned'

    def createShopDict(soup):
      itemDict = {}
      for e in soup.findAll('tr'):
        if findall('^\<tr\>\<td width\=', str(e)):
          numItems = None
          tds = e.findAll('td', attrs={'width':60})
          if len(tds) == 0 or len(tds[0].contents) == 0:
            continue
          n = tds[0].contents[0]
          item = sub("</?[^\W].{0,1000}?>",'', str(n))
          for o in e.findAll('select'):
            numItems = max([i.contents[0] for i in o.findAll('option')])
          selects = e.findAll('select')
          if len(selects) > 0:
            attr = selects[0].attrs[0][1]
          if numItems:
            itemDict[item] = {'num' : int(numItems), 'attr' : attr}
      return itemDict

    def getAuctionsDict():
      with open('auctionsFile.txt','r') as f:
        auctionsFile = f.read()
      auctionItems = [a for a in auctionsFile.splitlines() if a.strip() != '']
      auctionsDict = {}
      for e in auctionItems:
        try:
          item, price, increment, timeList = e.split('\t')
          auctionsDict[item] = {'price':int(price), 'increment':int(increment), 'count' : 0, 'timeList' : timeList.strip().replace(' ','').split(',')}
        except:
          pass
      return auctionsDict

    def getNumCurrentAuctionedItems(resp):
      return len(findall('\(auctioned\)', str(resp)))

    def getPostReqDict(shopDict, auctionsDictFromFile, currNumAuctions):
      postReqDict = {}
      for item in auctionsDictFromFile :
        if item in shopDict and currNumAuctions < 8:
          postReqDict[shopDict[item]['attr']] = 0
          numOfCurrItem = shopDict[item]['num']
          while numOfCurrItem > 0 and currNumAuctions < 8:
            postReqDict[shopDict[item]['attr']] += 1
            currNumAuctions += 1
            numOfCurrItem -= 1
      for e in postReqDict:
        postReqDict[e] = [str(postReqDict[e])]
      return postReqDict

    def getItemsToAuctionFromInv(s):
      try:
        itemTable = s.findAll('table', attrs={'width':'100%', 'align':'center'})[0]
      except IndexError:
        return []
      itemTds = itemTable.findAll('td')
      invList = []
      for item in itemTds:
        if 'auctioned' not in str(item):
          name = item.contents[2]
          itemId = findall('openwin\((\d+)\)', str(item.contents[0]))[0]
          invList.append((name,itemId))
      return invList

    def getValidTimesList(timeList):
      validList = []
      for hour in timeList:
        if hour in ['1','2','3','4','6','9','12','18','24','48']:
          validList.append(hour)
      return validList

    def auctionItem(item, id, auctionsDictFromFile):
      self.doSleep(sleepSecondsList.pop())
      resp = self.doOpen('http://www.neopets.com/iteminfo.phtml?obj_id=%s' % (str(id)), 'logs/itemAuctionB4%s.html' % str(id))
      s = BeautifulSoup(resp)
      self.br.select_form(nr=0)
      for option in s.findAll('form', attrs={'name':'item_form'})[0].findAll('option'):
        val = option.attrs[0][1]
        if 'uction' in val:
          self.br['action'] = [val]
          try:
            resp = self.br.submit()
          except:
            raise
          html = resp.read()
          writeToFile(html, self.getLogFile('logs/itemAuctionDuring%s.html' % str(id)))

          self.br.select_form(nr=0)
          self.br['start_price'] = str(auctionsDictFromFile[item]['price'])
          self.br['min_increment'] = str(auctionsDictFromFile[item]['increment'])
          self.br['duration'] = ['4']
          timeList = getValidTimesList(auctionsDictFromFile[item]['timeList'])
          if timeList:
            currIndex = auctionsDictFromFile[item]['count']
            indexForThisTime = timeList[-1::]
            if currIndex < len(timeList):
              indexForThisTime = currIndex
            self.br['duration'] = [timeList[indexForThisTime]]
          self.doSleep(sleepSecondsList.pop())
          try:
            resp = self.br.submit()
          except:
            raise
          html = resp.read()
          writeToFile(html, self.getLogFile('logs/itemAuctionAfter%s.html' % str(id)))
          return 'Auctioned item %s for %s with increment of %s' % (item, str(auctionsDictFromFile[item]['price']), str(auctionsDictFromFile[item]['increment']))

    resp = self.doOpen(data['invurl'], data['invFileToWrite'])
    currNumAuctions = getNumCurrentAuctionedItems(resp)
    if currNumAuctions >= 8:
      return 'Already have 8 items auctioned'
    self.doSleep(sleepSecondsList.pop())
    resp = self.doOpen(data['url'], data['shopFileToWrite'])
    soup = BeautifulSoup(resp)

    shopDict = createShopDict(soup)
    auctionsDictFromFile = getAuctionsDict()
    postReqDict = getPostReqDict(shopDict, auctionsDictFromFile, currNumAuctions)
    if postReqDict:
      self.selectPhraseAndSubmit(sleepSecondsList.pop(), data, postReqDict)

    #Back to inv
    self.doSleep(sleepSecondsList.pop())
    resp = self.doOpen(data['invurl'], data['invFileToWrite2'])
    invSoup = BeautifulSoup(resp)

    itemsInInv = getItemsToAuctionFromInv(invSoup)

    auctionResults = []
    for item, id in itemsInInv:
      if item in auctionsDictFromFile:
        auctionResults.append( auctionItem(item, id, auctionsDictFromFile) )
        auctionsDictFromFile[item]['count'] += 1
    return '\n'+'\n'.join(auctionResults)


  def getFeedOmelette(self, sleepSecondsList, omelette, petName):
    def doEat( index ):
      self.doSleep(sleepSecondsList.pop())
      resp = self.doOpen('http://www.neopets.com/iteminfo.phtml?obj_id=%s' % itemId[0], 'logs/omelette%s.html' % index)
      self.doSleep(sleepSecondsList.pop())
      s = BeautifulSoup(resp)
      self.br.select_form(nr=0)
      for option in s.findAll('form', attrs={'name':'item_form'})[0].findAll('option'):
        val = option.attrs[0][1]
        if 'Feed to %s' % petName in val:
          self.br['action'] = [val]
          try:
            resp = self.br.submit()
          except:
            print self.br.geturl()
            raise
          html = resp.read()
          writeToFile(html, self.getLogFile('logs/eatOmelette%s.html' % index))
          return 'Ate'
      return None

    resp = self.doOpen('http://www.neopets.com/objects.phtml?type=inventory', 'logs/inventory.html')
    if self.getPetHunger().lower() not in ['dying', 'starving', 'famished', 'very hungry', 'hungry ']:
      return 'Pet not hungry enough to feed.'
    self.doSleep(sleepSecondsList.pop())
    if self.testMode:
      return 'Test Mode, probably fed omelette'
    soup = BeautifulSoup(resp)
    w = None
    for a in soup.findAll('a'):
      if '%s.gif' % omelette in str(a):
        w = str(a)
    itemId = findall('openwin\((\d+)\)', str(w))
    ateList = []
    if len(itemId)>0:
      for i in range(3):
        ate = doEat( str(i))
        if not ate:
          break
        else:
          ateList.append(ate)
      return 'Ate %s times' % str(len(ateList))
    return 'Cannot find omelette'


  def getItemsIntoShop(self, sleepSeconds):
    resp = self.doOpen('http://www.neopets.com/quickstock.phtml', 'logs/stockbefore.html')
    self.doSleep(sleepSeconds)
    if self.testMode:
      return 'Probably did something to restock'
    index = self.findFormIndexByStr("quickstock POST http://www.neopets.com/process_quickstock.phtml")
    self.br.select_form(nr=index)
    stockingRadios = []
    for c in self.br.form.controls:
      if hasattr(c, 'name') and c.name and 'radio_arr' in c.name:
        for item in c.items:
          if item.name == 'stock':
            self.br[c.name] = ['stock']
            stockingRadios.append(c.name)
            break
    if len(stockingRadios) == 0:
      return 'No items available to stock'
    stockingDict = {}
    soup = BeautifulSoup(resp)
    for tr in soup.findAll('tr'):
      if 'input type="radio" name="radio_arr' in str(tr) and 'stock' in str(tr) and len(str(tr))<3000:
        for at in tr.findAll('input', attrs={'type':'radio','value':'stock'})[0].attrs:
          if str(at[0]) == 'name':
            stockingDict[at[1]] = tr.findAll('td', attrs={'align':'left'})[0].contents[0]
    self.br['checkall'] = ['on']
    try:
      resp = self.br.submit()
    except:
      print self.br.geturl()
      raise
    html = resp.read()
    writeToFile(html, self.getLogFile('logs/stockAfter.html'))
    return str([str(stockingDict[e]) for e in stockingRadios])


  def checkMail(self, sleepSecondsList):
    if self.testMode:
      return 'MUST HAVE READ MAIL'

    def getMailsToRead(html):
      soup = BeautifulSoup(html)
      mailsToRead = []
      try:
        form = soup.findAll( 'form', attrs={ 'name':"messages", 'action':"modify_neomessages.phtml"})[0]
      except:
        return mailsToRead
      for tr in form.findAll('tr')[1:][:-1]:
        if 'Unread' in str(tr):
          links = tr.findAll('a')
          for link in links:
            if 'read_message' in str(link):
              mailsToRead.append( dict(link.attrs)['href'] )
      return mailsToRead

    def getMailMessage(html):
      soup = BeautifulSoup(html)
      table = soup.findAll( 'table', attrs={'border':"0", 'cellpadding':"6"})[0]
      for tr in table.findAll('tr'):
        if '<b>Message:</b>' in str(tr):
          return str(tr.findAll('td')[1].contents).replace('\\n','')
      return ''

    def parseAutomatedMessage(msg):
      if 'You will be pleased to know that your Neopets auction' in msg:
        item = findall('Neopets auction Lot No. \d+ \((.+)\) has been ', msg)[0]
        soldFor = findall('and that (\d+) NeoPoints have been credited to your account', msg)[0]
        return 'Sold %s for %s' % (item, str(soldFor))

      if 'because you have been granted the following item' in msg:
        item = findall('because you have been granted the following item : (.+) It will be ', msg)[0]
        return 'Wishing well gave: %s' % item

      if 'has not been successful, because nobody placed a bid' in msg:
        item = findall('Auction ID # \d+ \((.+)\), has not', msg)[0]
        return 'Unsuccessful auction: %s' % item
      return False

    def deleteMails(mailsToDelete):
      resp = self.doOpen(data['url'], 'logs/beforeDeleteMail.html')
      formIndex = self.findFormIndexByStr(data['phraseInForm'])
      self.br.select_form(nr=formIndex)
      self.br['action'] = ['Delete Messages']
      self.br['checkbox_arr[]'] = mailsToDelete
      resp = self.br.submit()
      html = resp.read()
      with open(self.getLogFile('logs/afterDeleteMails.html'),'w') as f:
        f.write(html)

    returnInfo = ''
    mailsToDelete = []
    data = fdd.dailyData['Check mail']
    resp = self.doOpen(data['url'], data['fileToWrite'])

    listOfMailLinks = getMailsToRead(resp)
    for link in listOfMailLinks:
      self.doSleep(sleepSecondsList.pop())
      linkId = findall('id=(\d+)',link)[0]
      resp = self.doOpen('http://www.neopets.com/%s' % link, data['filesToWrite'] % linkId)
      msg = getMailMessage(resp)
      automatedMsg = parseAutomatedMessage(msg)
      if automatedMsg:
        mailsToDelete.append(linkId)
        returnInfo += '\n'+automatedMsg

    if mailsToDelete:
      self.doSleep(sleepSecondsList.pop())
      deleteMails(mailsToDelete)

    self.userLog(returnInfo, True)
    return returnInfo


  def goToGame(self, gameID, sleepSecondsList):
    self.currentGameDict = {'gameID' : gameID}
    self.doOpen('http://www.neopets.com/games/arcade.phtml', 'logs/arcade.html')
    self.doSleep(sleepSecondsList.pop())
    resp = self.doOpen('http://www.neopets.com/games/play.phtml?game_id=%d' % (gameID))
    if "Sorry, this game is not available!" in resp:
      return '%s not available' % gameID
    self.doSleep(sleepSecondsList.pop())
    #SHOULD WRAP IN TRY in case these fail
    self.currentGameDict['numPlayed'] = int(findall('Scores Sent: <span class="red">(\d+)</span>', resp)[0])
    self.currentGameDict['recycle'] = findall('''return \'\/games\/play_flash.phtml\?([^']+)''', resp)[0]
    self.currentGameDict['width'] = findall('''size_arr\[\"regular\"\]\[\"width\"\] \= (\d+)''', resp)[0]
    self.currentGameDict['height'] = findall('''size_arr\[\"regular\"\]\[\"height\"\] \= (\d+)''', resp)[0]
    [self.currentGameDict['ratioPoints'], self.currentGameDict['ratioNP']] = findall('''(\S+) POINTS = <span .+>(\d+) NP''', resp)[0]

    if numPlayed >= 3:
      return 'Played 3 times already'
    req = 'http://www.neopets.com/games/play_flash.phtml?%s&width=%s&height=%s&quality=high' % (recycle, width, height)
    resp = self.doOpen(req, 'flashRESPONSE.html')
    self.currentGameDict['count'] = 0
    if self.currentGameDict['count'] == 0:
      self.currentGameDict['count'] = time()

    gameDict = eval(findall('({"gameURL".+})\,', resp)[0])
    URL = gameDict['gameURL']
    self.currentGameDict['sendreferrer'] = URL.split('?')[0] # loader!
    self.currentGameDict['gameName'] = self.htmlDecode(gameDict['gameName'])

    urlParts = self.ParseStr(URL)
    includemovie = self.htmlDecode(urlParts['include_movie'])
    self.currentGameDict['referrer'] = "%s/%s" % (self.htmlDecode(urlParts['image_host']), includemovie)
    self.currentGameDict['challenge'] = int(urlParts['ddNcChallenge'])

    if self.currentGameDict['gameID'] in [877, 925, 926]:
      return "Non-flash game..."


    if self.lastPlayedID == self.currentGameDict['gameID'] and self.hashkey.has_key('sk') and self.hashkey.has_key('sh'):
      self.currentGameDict['SH'] = self.hashkey['sh']
      self.currentGameDict['SK'] = self.hashkey['sk']
    else:
      self.currentGameDict['SH'] = urlParts['sh']
      self.currentGameDict['SK'] = urlParts['sk']
      p = urlParts['p']
      if 'preloader_acup' in p:
        self.doSleep(1)
        self.doOpen("http://www.neopets.com/process_click.phtml?item_id=18017&noredirect=1", referer = self.currentGameDict['referrer'])
    self.currentGameDict['f'] = urlParts['f']

    ##### SLEEP FOR TIME IN PARSED SS
    for e in self.currentGameDict:
      print e, self.currentGameDict[e]


  def sendCurrentGameScore(self):
    countDiff = str((time() - count)*1000)
    newcount = int(countDiff.split(".")[0])
    holdcrypt = "ssnhsh=%s&ssnky=%s&gmd=%d&scr=%d&frmrt=%d&chllng=%d&gmdrtn=%d" % (SH, SK, game_id, score, f, challenge, newcount)
    recycle = "&ddNcChallenge=%d" % challenge

    link = "http://www.neopets.com/high_scores/process_flash_score.phtml?cn=%d&gd=%d&asp_fs_g=&r=0.%d&gmd_g=%d&mltpl_g=0&gmdt_g=%s&sh_g=%s&sk_g=%s&usrnm_g=%s&dc_g=%d&cmgd_g=%d%s&fs_g=0"
    values = (game_id * 300, newcount, random.randrange(0, 999999999), game_id, self.NPEncrypt(holdcrypt, SH, SK), SH, SK, self.username, int(DC), int(ivid), recycle)
    URL = link % values


#-------------------stolen ss code >.< --------------------#
  def ParseStr(self, html):
    results = {}
    questionmark = html.find("?")
    if(questionmark != -1):
      questionmark += 1
      html = html[questionmark:]
    temp = html.split('&')
    for i in range(len(temp)):
      temp[i] = temp[i].split('=')
      results[temp[i][0]] = temp[i][1]
    return results

  htmlCodes = [
    ['&', '&amp;'],
    ['<', '&lt;'],
    ['>', '&gt;'],
    ['"', '&quot;'],
  ]
  htmlCodesReversed = htmlCodes[:]
  htmlCodesReversed.reverse()
  def htmlDecode(self, s, codes=htmlCodesReversed):
    for code in codes:
      s = s.replace(code[1], code[0])
    return s

#-------------------stolen ss code >.< --------------------#



  def getShopSpace(self):
    return self.shopSpace

  def getNP(self):
    return str(self.np)

  def getCurrentPet(self):
    return self.currentPet

  def getPetHunger(self):
    return self.hunger

  def getPetMood(self):
    return self.mood

  def getBankTotal(self):
    return self.bankTotal


  def userLog(self, infoToLog, importantLog=False):
    try:
      stuffToLog = '[%s] %s' % (self.username, infoToLog)
    except:
      stuffToLog = '[%s] %s' % (self.username, str(infoToLog))
    if importantLog:
      logger.info(stuffToLog)
    detailedLogger.info(stuffToLog)


  def doOpen(self, url, fileToWrite=None, postData=False, loginCheck=True, referer = False):
    def getHtmlResponse():
      if isinstance(url, Request):
        if postData:
          response = self.br.open( url, postData)
        else:
          response = self.br.open( url )
        return response.read()


      req = Request( url )
      if postData:
        req = Request( url, postData )
      if referer:
        req.add_header("Referer", referer)
        self.cj.add_cookie_header(req)
      response = self.br.open( req )
      return response.read()

    self.userLog('%s [%s]' % (url, str(type(url))))
    if not self.testMode:
      try:
        htmlResponse = getHtmlResponse()
      except IncompleteRead as e:
        sleep(1.5)
        htmlResponse = getHtmlResponse()
      except TypeError as e:
        sleep(1.8)
        print e, 'type err, trying again'
        htmlResponse = getHtmlResponse()
      except Exception as e:
        timeToSleepFor = 300
        
        logger.info( e )
        self.userLog(e, True)
        self.userLog(traceback.format_exc())
        self.userLog( 'Caught URLERROR, waiting %s seconds to try again' % timeToSleepFor )
        self.doSleep(timeToSleepFor)
        htmlResponse = getHtmlResponse()
      self.currentUrl = self.br.geturl()
      if loginCheck==True and (self.username not in repr(str(htmlResponse))):
        htmlResponse = self.tryRelogin()
      soup = BeautifulSoup(htmlResponse)
      try:
        self.np = int(str(soup.findAll('a',attrs={'id':'npanchor'})[0].contents[0]).replace(',',''))
      except:
        pass
      try:
        self.currentPet = sub("</?[^\W].{0,1000}?>",'', str(soup.findAll('a',{'href':'/quickref.phtml'})[0].contents[0]))
      except:
        pass
      try:
        freeSpace = findall("""Free Space : <b>(\d+)</b>""", htmlResponse)
        if freeSpace:
          self.shopSpace = freeSpace[0]
      except:
        pass
      try:
        tdList = soup.findAll("td", {"class": "activePetInfo"})[0].findAll("td")
        hunger = ''
        for index, td in enumerate(tdList):
          if "Hunger" in str(td):
            self.hunger = sub("</?[^\W].{0,1000}?>",'', str(tdList[index+1]))
      except:
        pass
      try:
        tdList = soup.findAll("td", {"class": "activePetInfo"})[0].findAll("td")
        hunger = ''
        for index, td in enumerate(tdList):
          if "Mood" in str(td):
            self.mood = sub("</?[^\W].{0,1000}?>",'', str(tdList[index+1]))
      except:
        pass
      if fileToWrite:
        writeToFile(htmlResponse, self.getLogFile(fileToWrite))
      self.saveCookie()
      return htmlResponse
    return 'testresponse'


  def tryRelogin(self):
    foundLoginForm = False
    for index, form in enumerate(self.br.forms()):
      if """<login POST http://www.neopets.com/login.phtml""" in str(form):
        foundLoginForm = index
        break
    if foundLoginForm == False and foundLoginForm != 0:
      with open(self.getLogFile('logs/failedLogin.html'),'w') as f:
        f.write(htmlResponse)
      raise Exception('GOT LOGGED OUT Failed to log back in (unknown page)!!!!')
    self.br.select_form(nr=foundLoginForm)
    self.br['username'] = self.username
    self.br['password'] = self.password
    self.doSleep(randint(1,5))
    resp = self.br.submit()
    htmlResponse = resp.read()
    if self.username not in repr(str(htmlResponse)):
      with open(self.getLogFile('logs/failedLogin.html'),'w') as f:
        f.write(htmlResponse)
      raise Exception('GOT LOGGED OUT Tried to log back in and failed (unknown page)!!!!')
    return htmlResponse


  def doSleep(self, seconds):
    if not self.testMode:
      sleep(seconds)


def safe_str(obj):
  try:
    return str(obj)
  except UnicodeEncodeError:
    return unicode(obj).encode('unicode_escape')

def writeToFile(stuffToWrite, filename):
  with open(filename, 'w') as f:
    f.write(stuffToWrite)


class TimedOutReq:

  def read(self):
    return TIMEOUT_TOKEN



class TimeoutSubmit(Thread):
  def __init__(self, br):
    Thread.__init__(self)
    self.completed = False
    self.retVal = False
    self.br = br


  def run(self):
    self.retVal = self.br.submit()
    self.completed = True

  def isComplete(self):
    return self.completed
